package com.secondriver.url.admin.groovy

import com.secondriver.url.filter.SysConfig;

import groovy.json.JsonOutput;
import groovy.sql.DataSet;
import groovy.sql.Sql;

import java.sql.SQLException

class AdminServiceDao {

	def conn;

	def dbConfig;

	def SysConfig sysConfig =new SysConfig();

	def  AdminServiceDao(dbConfig){
		if(null == dbConfig || dbConfig.size() ==0){
			throw new IllegalArgumentException(AdminServiceDao.getClass().getName()+' constructor method parameter dbConfig must not null, this is database connection configuration for query.');
		}
		def config=[:];
		if(dbConfig instanceof Map){
			config=dbConfig;
		}else if(dbConfig instanceof String){
			def kv=dbConfig.tokenize(sysConfig.constant.tokenzie);
			kv.each({ str ->
				def index=str.indexOf(sysConfig.constant.configSep, 0);
				if(index > 0){
					config[str.substring(0, index)]=str.substring(index+1);
				}
			})
		}else{
			throw new IllegalArgumentException(AdminServiceDao.getClass().getName()+
			' contructor method parameter type must be Map or String.');
		}
		this.dbConfig=config;
	}

	/**
	 * 业务处理
	 */
	def methods=[
		page:{ params->
			def requireParams=['table'];
			if(requireParamsCheck.call(params, requireParams)){
				def table=params['table'];
				def sql='select count(1) as total from '+table;
				try{
					this.openConn();
					def total=this.conn.firstRow(sql).get('total');
					return '{"total":'+total+'}';
				}catch(Exception e){
					exceptions.sqlerror.call(params);
				}finally{
					this.closeConn();
				}
			}else{
				exceptions.paramerror.call(params);
			}
		},
		query:{ params->
			def requireParams=['table', 'pageNumber', 'pageSize'];
			if(requireParamsCheck.call(params, requireParams)){
				def table =params['table'];
				def pageNumber=params['pageNumber'];
				def pageSize=params['pageSize'];
				if((pageNumber instanceof String && pageSize instanceof String)||
				(pageNumber instanceof Integer && pageSize instanceof Integer)){
					pageNumber=pageNumber.toInteger();
					pageSize=pageSize.toInteger();
				}else{
					exceptions.paramerror.call(params);
				}

				StringBuilder sb=new StringBuilder();
				def sql='select * from '+table;
				try{
					this.openConn();
					sb.append("[");
					this.conn.rows(sql, pageNumber*pageSize, pageSize).each { map->
						sb.append(JsonOutput.toJson(map));
					};
					sb.append("]");
					return sb.toString() ;
				}catch(SQLException e){
					exceptions.sqlerror.call(params);
				}finally{
					this.closeConn();
				}
			}else{
				exceptions.paramerror.call(params);
			}
		},
		insert:{ params->
			def requireParams=['table', 'data'];
			if(requireParamsCheck.call(params, requireParams)){
				def table =params['table'];
				def data=params['data'];
				//这里需要对data进行类型转换
				try{
					this.openConn();
					DataSet ds=new DataSet(this.conn, table);
					ds.add(data);
					ds.close();
					return '{"msg":"添加成功"}';
				}catch(Exception e){
					exceptions.sqlerror.call(params);
				}finally{
					this.closeConn();
				}
			}else{
				exceptions.paramerror.call(params);
			}
		},
		delete:{ params->
			def requireParams=['table', 'data'];
			if(requireParamsCheck.call(params, requireParams)){
				def table=params['table'];
				def data=params['data'];
				def dataRequire=['pkname', 'pkvalue'];
				if(requireParamsCheck.call(data, dataRequire)){
					def pkname=data['pkname'];
					def pkvalue=data['pkvalue'];
					def sql='delete from '+table+' where '+pkname+' = ?';
					try{
						this.openConn();
						int rs=this.conn.executeUpdate(sql, [pkvalue]);
						return rs > 0 ?'{"msg":"删除成功"}':'{"msg":"删除失败"}';
					}catch(Exception e){
						exceptions.sqlerror.call(params);
					}finally{
						this.closeConn();
					}
				}else{
					exceptions.paramerror.call(params);
				}
			}else{
				exceptions.paramerror.call(params);
			}
		},
		install:{ params->
			def requireParams=['db'];
			if(requireParamsCheck.call(params, requireParams)){
				Properties p=sysConfig.getSqlScript();
				def db=params['db'];
				def script=[];
				sysConfig.supportTable.each{ it->
					def sql=p.get(db+sysConfig.constant.tokenzie+it);
					if(null !=sql){
						script << sql;
					}
				}
				try{
					this.openConn();
					def rs=	this.conn.withBatch(script.size()){stmt->
						script.each { sql->
							stmt.addBatch(sql);
						}
					}
					return '{"msg":"安装成功"}';
				}catch(Exception e){
					params['msg']='安装失败';
					exceptions.sqlerror.call(params);
				}finally{
					this.closeConn();
				}
			}else{
				exceptions.paramerror.call(params);
			}
		}
	]

	def requireParamsCheck={ params, requireParams->
		return requireParams.every {   it->
			return null!=params[it];
		}
	}

	def exceptions=[
		nomethod: { params->
			if(null == params['msg']){
				params['mgs']='请求处理异常';
			}
			return formateResult(params);
		},
		sqlerror:{ params->
			if(null == params['msg']){
				params['mgs']='SQL错误';
			}
			return formateResult(params);
		},
		paramerror:{ params->
			if(null == params['msg']){
				params['mgs']='请求参数异常';
			}
			return formateResult(params);
		}
	];

	private def formateResult={ params->
		return JsonOutput.toJson(params);
	}

	def execute(String method, Map params){
		if(methods.containsKey(method)){
			return	methods.getAt(method).call(params);
		}else{
			return	exceptions.nomethod.call(params);
		}
	}

	def service(java.util.Map params){
		def method=params['method']
		params.remove('method');
		return this.execute(method, params);
	}

	private def openConn(){
		this.conn=Sql.newInstance(
				this.dbConfig.url,
				this.dbConfig.user,
				this.dbConfig.password,
				this.dbConfig.driver);
		return this;
	}

	private def closeConn(){
		this.conn?.close();
		return this;
	}
}
